import assetsStore from '../store/assets';
import { IAssetObject } from '../store/types';
import pluginsStore from '../store/plugins';
import { cloneDeep } from 'lodash';
import { toRaw } from 'vue';

interface SailGameObjectScript extends cc.Component {
    bundle: string;
    originObjectID: string;
    props: cc.Component;
    variables: sail.Variable[];
}

export async function getNodeProperty(script: SailGameObjectScript): Promise<sail.ComponentAttr[]> {
    const allProps: sail.ComponentAttr[] = [];
    const { bundle } = script;
    const bundleInfo = await sail.loadBundle(bundle);
    if (bundleInfo && bundleInfo.component) {
        const attrs = sail.getComponentAttrs(bundleInfo.component);
        const props = script.node.getComponent(bundleInfo.component);
        for (let i = 0; i < attrs.length; i++) {
            let attr = attrs[i];
            const key = attr.name;
            allProps.push({
                default: attr.default,
                name: key || '',
                displayName: attr.displayName,
                tooltip: attr.tooltip || '',
                visible: !!attr.visible,
                // @ts-ignore
                value: props[key],
            });
        }
    }
    return allProps;
}

interface InstanceVariable {
    id: string,
    value: any,
}

export function getNodeVariables(script: SailGameObjectScript): sail.Variable[] {
    
    const { bundle, originObjectID } = script;
    const variables: InstanceVariable[] = script.variables;
    
    // 先检索出来对象的所有变量
    let objVariables: sail.Variable[] = [];
    const asset = assetsStore().getAsset(originObjectID);
    if (asset) {
        const objAsset = asset as IAssetObject;
        objVariables = cloneDeep(toRaw(objAsset.data.vars));
    }
    
    const ret: sail.Variable[] = [];
    objVariables.forEach(variable => {
        const find = variables.find(el => el.id === variable.id);
        if (find) {
            variable.value = find.value;
        }
        ret.push(variable);
    });
    
    return ret;
}

export function getNodeBehaviors(script: SailGameObjectScript): Record<string, sail.ComponentAttr[]> {
    const { bundle, originObjectID } = script;
    // @ts-ignore
    const hasBehaviorsData: Record<string, sail.ComponentAttr[]> = script.dumpBehaviorData();
    const kes = Object.keys(hasBehaviorsData);
    // 先检索出来关联对象的所有行为
    let objBehaviors: string[] = [];
    const asset = assetsStore().getAsset(originObjectID);
    if (asset) {
        const objAsset = asset as IAssetObject;
        objBehaviors = objAsset.data.behaviors;
    }
    const ret: Record<string, sail.ComponentAttr[]> = {};
    objBehaviors.forEach(behavior => {
        if (kes.find(el => el === behavior)) {
            ret[behavior] = hasBehaviorsData[behavior];
        } else {
            const plugin: sail.GameBehavior | null = pluginsStore().getBehaviorByID(behavior);
            if (plugin) {
                const comp = sail.getComponentAttrs(plugin.component);
                const instance = script.node.getComponent(plugin.component);
                if (instance) {
                    comp.forEach(item => {
                        // @ts-ignore
                        item.value = instance[item.name];
                    });
                    ret[behavior] = comp;
                } else {
                    console.warn('节点没有添加行为脚本:', plugin.component);
                }
            }
        }
    });
    return ret;
}